use std::error::Error;
use std::sync::Arc;
use std::time::{Duration, Instant};
use tokio::sync::RwLock;
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use log::{error, warn, info};

use super::DataSource;

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct HealthStatus {
    pub is_healthy: bool,
    pub last_check_time: DateTime<Utc>,
    pub response_time: Duration,
    pub error_count: u32,
    pub consecutive_failures: u32,
    pub last_error: Option<String>,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PerformanceMetrics {
    pub avg_response_time: Duration,
    pub min_response_time: Duration,
    pub max_response_time: Duration,
    pub request_count: u64,
    pub error_rate: f64,
    pub last_update: DateTime<Utc>,
}

pub struct HealthChecker {
    source: Arc<Box<dyn DataSource>>,
    status: Arc<RwLock<HealthStatus>>,
    metrics: Arc<RwLock<PerformanceMetrics>>,
    check_interval: Duration,
    error_threshold: u32,
}

impl HealthChecker {
    pub fn new(source: Arc<Box<dyn DataSource>>, check_interval: Duration, error_threshold: u32) -> Self {
        let status = HealthStatus {
            is_healthy: true,
            last_check_time: Utc::now(),
            response_time: Duration::from_secs(0),
            error_count: 0,
            consecutive_failures: 0,
            last_error: None,
        };

        let metrics = PerformanceMetrics {
            avg_response_time: Duration::from_secs(0),
            min_response_time: Duration::from_secs(u64::MAX),
            max_response_time: Duration::from_secs(0),
            request_count: 0,
            error_rate: 0.0,
            last_update: Utc::now(),
        };

        Self {
            source,
            status: Arc::new(RwLock::new(status)),
            metrics: Arc::new(RwLock::new(metrics)),
            check_interval,
            error_threshold,
        }
    }

    pub async fn start_monitoring(&self) {
        let status = self.status.clone();
        let metrics = self.metrics.clone();
        let source = self.source.clone();
        let interval = self.check_interval;
        let error_threshold = self.error_threshold;

        tokio::spawn(async move {
            let mut interval = tokio::time::interval(interval);
            loop {
                interval.tick().await;
                
                // 执行健康检查
                let start_time = Instant::now();
                let check_result = source.get_market_sentiment().await;
                let response_time = start_time.elapsed();

                let mut status = status.write().await;
                let mut metrics = metrics.write().await;

                // 更新性能指标
                metrics.request_count += 1;
                metrics.avg_response_time = Duration::from_nanos(
                    (metrics.avg_response_time.as_nanos() * (metrics.request_count - 1) as u128 
                    + response_time.as_nanos()) / metrics.request_count as u128 as u64
                );
                metrics.min_response_time = metrics.min_response_time.min(response_time);
                metrics.max_response_time = metrics.max_response_time.max(response_time);
                metrics.last_update = Utc::now();

                match check_result {
                    Ok(_) => {
                        status.is_healthy = true;
                        status.consecutive_failures = 0;
                        status.last_error = None;
                        metrics.error_rate = status.error_count as f64 / metrics.request_count as f64;
                    }
                    Err(e) => {
                        status.error_count += 1;
                        status.consecutive_failures += 1;
                        status.last_error = Some(e.to_string());
                        metrics.error_rate = status.error_count as f64 / metrics.request_count as f64;

                        if status.consecutive_failures >= error_threshold {
                            status.is_healthy = false;
                            warn!("Data source {} health check failed: consecutive failures exceeded threshold",
                                source.name());
                        }
                    }
                }

                status.last_check_time = Utc::now();
                status.response_time = response_time;
            }
        });
    }

    pub async fn get_health_status(&self) -> HealthStatus {
        self.status.read().await.clone()
    }

    pub async fn get_performance_metrics(&self) -> PerformanceMetrics {
        self.metrics.read().await.clone()
    }

    pub async fn is_healthy(&self) -> bool {
        self.status.read().await.is_healthy
    }
}